home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / wb / czesc_2 / memmometer / src / mm.c < prev    next >
C/C++ Source or Header  |  1992-11-06  |  56KB  |  1,768 lines

  1. /* : ai=0 bk=0 ts=8 */
  2. #ifdef TALKTOREXX
  3. /*
  4.  *  MinRexx include file
  5.  */
  6. char *VERSION = "MemMometer, Version 2.40 w ARexx" ;
  7. #include "minrexx.h"
  8. #else
  9. char *VERSION = "MemMometer, Version 2.39" ;
  10. #endif
  11.  
  12. #include "mm.h"
  13.  
  14. #define FREEPEN -1L           /* workbench screen default colors */
  15. #define REQ_WINDOW_WIDTH 319L /* width of warning requester window */
  16. #define REQ_WINDOW_HEIGHT 79L /* height of warning requester window */
  17.  
  18. #define SOK        0x001f     /* memory allocation control masks */
  19. #define S1         0x0001
  20. #define S2         0x0002
  21. #define S4         0x0004
  22. #define S8         0x0008
  23. #define SA         0x0010
  24. #define C1         0xfffe
  25. #define C2         0xfffd
  26. #define C4         0xfffb
  27. #define C8         0xfff7
  28. #define CA         0xffef
  29. #define AARRRGH    20L         /* hang 20, cats, we're startin ta curl! */
  30.  
  31. #define EXTENSION  16L         /* allocation request increment */
  32.  
  33. #define FRAGS FALSE                          /* frags mode control boolian */
  34. #define WARPS TRUE                           /* warps mode control boolian */
  35. #define EVENMASK 0x7ffffffe           /* used to prevent odd address traps */
  36. #define CLIHEIGHT 200L                             /* window scaling stuff */
  37. #define SIZEGAD 9L
  38. #define DRAGBAR 10L
  39. #define BORDER 2L
  40. #define WINW 16L                                   /* initial window width */
  41. #define WINH (long)(CLIHEIGHT - SIZEGAD - DRAGBAR)   /* initial win height */
  42. #define MINH 81L                              /* shortest allowable window */
  43. #define MAXH 576L                              /* longest allowable window */
  44. #define BART 1L                               /* title bar F text location */
  45. #define BARH (long)(WINH - SIZEGAD - DRAGBAR)                /* bar height */
  46. #define BARS (long)(BARH + 1)        /* number of memory items to allocate */
  47. #define BARB (long)(BARH + DRAGBAR - 1)        /* bottom of mercury column */
  48. #define BARE (long)(BARB + BORDER)              /* bar end E text position */
  49. #define BARW (long)(((WINW - (2 * BORDER)) / 3) - 1)  /* 3 memfragmometers */
  50. #define LEFT BORDER                   /* SLOW : since we're syncopated, we */
  51. #define MIDDLE (LEFT + BARW + 1)      /* SLOW-FAST : do it going from bar  */
  52. #define RIGHT (MIDDLE + BARW + 1)     /* FAST :to bar at an irregular pace */
  53. #define RTEXT - 4L        /* offset for three char E/F text from left edge */
  54. #define STARTVAL 64L    /* start by getting enough storage for a few frags */
  55. #define TMARK 100000L                     /* timer granule in microseconds */
  56. #define TICKIES (long)(1000000/TMARK)       /* number of TMARKS per second */
  57.  
  58. /* typedef short BOOL */        /* this is in include/exec/types.h */
  59.  
  60. struct IntuitionBase *IntuitionBase=NULL ;
  61. struct Window *window ;
  62. struct IntuiMessage *NewMessage;
  63. /* struct IntuiMessage *GetMsg(); */        /* in functions.h */
  64.  
  65. struct GfxBase *GfxBase=NULL ;
  66.  
  67. struct IOStdReq *timermsg=NULL;
  68. struct MsgPort *timerport=NULL;
  69. ULONG  timerbit=NULL;
  70.  
  71.  
  72. extern void InitProjItems();        /* this stuff is in the mminit section */
  73. extern void InitSetupItems();
  74. extern void InitPrioItems();
  75. extern void InitChipItems();
  76. extern void InitChipAItems();
  77. extern void InitSFItems();
  78. extern void InitSFAItems();
  79. extern void InitFastItems();
  80. extern void InitFastAItems();
  81. extern void InitMenu();
  82. extern void StartMenus();
  83. #ifdef TALKTOREXX
  84. /*
  85.  * Menu Check Mark alteration for Rexx
  86.  */
  87. extern void DoCheckMenus();
  88. #endif
  89.  
  90. BOOL p_mode = FRAGS;          /* preset frags mode = 0, warps mode = 1 */
  91.                               /* note: mode preset used as request for */
  92.                               /*       change to warps mode after the  */
  93.                               /*       first pass with frags mode set! */
  94. long p_rate = 2;              /* preset sample interval, secs see menu */
  95. long p_priority = 0;          /* preset priority, range -128 to +127   */
  96.                               /* note: pri greater than zero is risky! */
  97.                               /* keep in mind AmigaDOS priorities:     */
  98.                               /* input.device 20, FileSystem 10, and   */
  99.                               /* trackdisk.device, CON: 5 also if MM   */
  100.                               /* is started from a CLI without the Run */
  101.                               /* then that CLI inherits MM's priority! */
  102. long p_chip = 512;            /* preset chip mem size, kbytes see menu */
  103. long p_chipa = 0;             /* preset chip mem address, kb  see menu */
  104. long p_sf = 0;                /* preset slowfast mem size, kb see menu */
  105. long p_sfa = 2048;            /* preset slowfast mem addr, kb see menu */
  106. long p_fast = 0;              /* preset fast mem size, mbytes see menu */
  107. long p_fasta = -1;            /* preset fast mem addr, mbytes see menu */
  108.                               /* zero or neg fasta is offset below the */
  109.                               /* A3000 fast ram ceiling, aka 0x8000000 */
  110.  
  111. static BOOL enforcer;                /* uninitialized for enforcer fix */
  112. static BOOL enforced;                /* uninitialized for enforcer fix */
  113. static BOOL pmchange;                /* uninitialized for mode change  */
  114. static BOOL cschange;                /* uninitialized for chip mem chg */
  115. static BOOL mode;                    /* uninitialized for mode control */
  116. static BOOL mmode;                   /* uninitialized for mode  menu   */
  117. static long delayval;                /* uninitialized for delay menu   */
  118. static long priority;                /* uninitialized for prioritymenu */
  119. static long basepri;                 /* uninitialized for priorityincr */
  120. static long cmemsize;                /* uninitialized for chip  menu   */
  121. static long cmembase;                /* uninitialized for chipa menu   */
  122. static long sfmemsize;               /* uninitialized for sf    menu   */
  123. static long sfmembase;               /* uninitialized for sfa   menu   */
  124. static long fmemsize;                /* uninitialized for fast  menu   */
  125. static long fmembase;                /* uninitialized for fasta menu   */
  126.  
  127. static USHORT log ;                  /* memory allocation success flags */
  128. static BOOL things_are_cool = TRUE ; /* tells when to close the window  */
  129. static BOOL intsig = FALSE ;         /* intuition message detector */
  130. static USHORT chgflag = TRUE ;       /* menu request to adjust columns */
  131. static long chip[3], fast[3] ;       /* place to keep mem header pointers */
  132. static ULONG  *chunkv ;              /* demand allocated for frag chunks */
  133. static ULONG  *sizev ;               /* demand allocated for frag sizes */
  134. static ULONG  *csum ;                /* a col's height worth of checksums */
  135. static ULONG  *oldcsum ;             /* same height worth of old checksums */
  136. static USHORT *cell;                 /* 1 cell per pixel height of mercury */
  137. static long xl, xr ;                 /* used to Draw() memmometer segments */
  138. static long frags = STARTVAL ;       /* # of demand allocated frag items */
  139. static long bars = BARS ;           /* # of demand allocated column items */
  140. static long barh = BARH ;            /* EVEN #'d height of mercury column */
  141. static long barb = BARB ;            /* bottom position of mercury column */
  142. static short ticker = TICKIES ;      /* initialized delay tick variable */
  143.  
  144. /* struct RastPort *rp ; */          /* wonder why we don't need this... ? */
  145.  
  146.  
  147. static struct TextAttr myfont = {
  148.    (STRPTR) "topaz.font",
  149.    TOPAZ_EIGHTY,
  150.    0,
  151.    0
  152. };
  153. /* E newsize gadget refresh text */ 
  154. static char ebuf[4] = " E " ;
  155. static struct IntuiText e_text = { 
  156.    BAKP, SHAP,
  157.    JAM2, 
  158.    0, BARE,
  159.    &myfont,
  160.    (UBYTE *)ebuf, 
  161.    NULL 
  162. };
  163. /* F title refresh text */
  164. static char fbuf[4] = " F " ;
  165. static struct IntuiText f_text = {
  166.    BAKP, SHAP,
  167.    JAM2,
  168.    0, BART,
  169.    &myfont,
  170.    (UBYTE *)fbuf,
  171.    &e_text
  172. };
  173. static struct NewWindow newwindow = {
  174.    0,                                        /* left edge */
  175.    10,                                       /* top edge */
  176.    WINW,                                     /* width */
  177.    WINH,                                     /* height */
  178.    0,                                        /* detail pen */
  179.    1,                                        /* block pen */
  180.    MENUPICK | NEWSIZE,                       /* messages */
  181. /* WINDOWDEPTH | WINDOWCLOSE */              /* don't use these gads */
  182.    WINDOWDRAG | WINDOWSIZING | NOCAREREFRESH,   /* add a few gadgets */
  183.    NULL,                                     /* no custom gadgets */
  184.    NULL,                                     /* default checkmark */
  185.    (UBYTE *)"F",                             /* title */
  186.    NULL,                                     /* initialize this! */
  187.    NULL,                                     /* use screen bitmap */
  188.    WINW, MINH, WINW, MAXH,                   /* min and max sizes */
  189.    WBENCHSCREEN } ;                          /* use workbench screen */
  190.  
  191. #ifdef TALKTOREXX
  192. /*
  193.  *  The following are program global definitions for our own Rexx functions.
  194.  */
  195.  
  196. #define TWOMEG       2097152L
  197. #define EIGHTMEG     8388608L
  198. #define CZERO       12582912L
  199. #define EZERO       14680064L
  200. #define SEVENOH     117440512L
  201.  
  202. /*
  203.  *     If we are talking to REXX, we need these additional locals.
  204.  */
  205.    long rexxbit ;
  206.    char firstcommand[256] ;
  207.  
  208. int dechecked = 0 ;         /* Menu check mark flags now invalidated    */
  209. int rechecked = 0 ;         /* Menu check mark flags now re-validated   */
  210. static BOOL refrshpre ;     /* Marks Rexx request redo preset variables */
  211.  
  212. /*
  213.  *  These are our REXX functions, as defined at the bottom of the file.
  214.  */
  215. void rexxfront(), rexxback(), rexxquit(), rexxmode(), rexxrate(),
  216.     rexxpriority(), rexxchipa(), rexxchip(), rexxsfa(), rexxsf(),
  217.     rexxfasta(), rexxfast(), rexxversion() ;
  218. void disp() ;
  219. /*
  220.  *  Here is our command association list.  Note that in this case,
  221.  *  we are setting the userdata field to be a function to call.
  222.  *  Dispatch will still take place through disp(), so common head
  223.  *  and tail stuff can go there.
  224.  *
  225.  *  Commands are all lower case, so we match either upper or lower.
  226.  *  (This is a requirement of minrexx.)
  227.  */
  228. struct rexxCommandList rcl[] = {
  229.    { "front", &rexxfront },
  230.    { "back", &rexxback },
  231.    { "quit", &rexxquit },
  232.    { "mode", &rexxmode },
  233.    { "rate", &rexxrate },
  234.    { "priority", &rexxpriority },
  235.    { "chipa", &rexxchipa },
  236.    { "chip", &rexxchip },
  237.    { "sfa", &rexxsfa },
  238.    { "sf", &rexxsf },
  239.    { "fasta", &rexxfasta },
  240.    { "fast", &rexxfast },
  241.    { "version", &rexxversion },
  242.    { NULL, NULL, } } ;
  243. #endif
  244.  
  245. void initmenus()
  246. {
  247.    (void) InitProjItems();              /* Initialize the menu items */
  248.    (void) InitSetupItems();
  249.    (void) InitPrioItems();
  250.    (void) InitChipItems();
  251.    (void) InitChipAItems();
  252.    (void) InitSFItems();
  253.    (void) InitSFAItems();
  254.    (void) InitFastItems();
  255.    (void) InitFastAItems();
  256.    (void) InitMenu();
  257.    (void) StartMenus();
  258.    }
  259.  
  260. void handle_MENUPICK( class, code )
  261. unsigned long class;
  262. unsigned int code;
  263. {
  264.     unsigned int menunum, itemnum, subnum;
  265.  
  266.     if (code == MENUNULL) return;
  267.  
  268.     menunum = MENUNUM( code );
  269.     itemnum = ITEMNUM( code );
  270.     subnum  = SUBNUM( code );
  271.     chgflag = TRUE;
  272.     switch( menunum ) {
  273.         case 0:
  274.         switch( itemnum ) {
  275.             case 0:
  276.             WindowToFront(window);
  277.             break;
  278.  
  279.             case 1:
  280.             WindowToBack(window);
  281.             break;
  282.  
  283.             case 2:
  284.             things_are_cool = FALSE;  /* Quit */
  285.             break;
  286.             } /* end of switch ( Project itemnum ) */
  287.         break;
  288.  
  289.         case 1:
  290.         switch( itemnum ) {
  291.             case 0:
  292.             switch( subnum ) {
  293.                 case 0:
  294.                 if ( mode == WARPS )  pmchange = TRUE ;
  295.                 mode = FRAGS ;          /* Frags mode */
  296.                 mmode = FALSE ;         /* cancel any pending request */
  297.                 break;
  298.  
  299.                 case 1:
  300.                 mmode = TRUE ;          /* Warps request */
  301.                 pmchange = TRUE ;       /* denotes request came from menu */
  302.                 break;
  303.                 /* end of switch ( Mode subnum ) */
  304.                 }
  305.             break;       
  306.             case 1:
  307.             switch( subnum ) {
  308.                 case 0:
  309.                 delayval = 1;
  310.                 break;
  311.  
  312.                 case 1:
  313.                 delayval = 2;
  314.                 break;
  315.  
  316.                 case 2:
  317.                 delayval = 5;
  318.                 break;
  319.  
  320.                 case 3:
  321.                 delayval = 10;
  322.                 break;
  323.                 /* end of switch ( Freq subnum ) */
  324.                 }
  325.             break;       
  326.             /* end of switch ( Setup itemnum ) */
  327.             }
  328.         break;
  329.  
  330.         case 2:
  331.         switch( itemnum ) {
  332.             case  0:
  333.             priority = basepri;
  334.             break;
  335.  
  336.             case  1:
  337.             priority = priority - 1;
  338.             break;
  339.  
  340.             case  2:
  341.             priority = priority + 1;
  342.             break;
  343.  
  344.             case  3:
  345.             priority = -99;
  346.             basepri = priority;
  347.             break;
  348.  
  349.             case  4:
  350.             priority = -75;
  351.             basepri = priority;
  352.             break;
  353.  
  354.             case  5:
  355.             priority = -50;
  356.             basepri = priority;
  357.             break;
  358.  
  359.             case  6:
  360.             priority = -25;
  361.             basepri = priority;
  362.             break;
  363.  
  364.             case  7:
  365.             priority = -20;
  366.             basepri = priority;
  367.             break;
  368.  
  369.             case  8:
  370.             priority = -15;
  371.             basepri = priority;
  372.             break;
  373.  
  374.             case  9:
  375.             priority = -10;
  376.             basepri = priority;
  377.             break;
  378.  
  379.             case 10:
  380.             priority =  -5;
  381.             basepri = priority;
  382.             break;
  383.  
  384.             case 11:
  385.             priority =   0;
  386.             basepri = priority;
  387.             break;
  388.  
  389.             case 12:
  390.             priority =   5;
  391.             basepri = priority;
  392.             break;
  393.  
  394.             case 13:
  395.             priority =  10;
  396.             basepri = priority;
  397.             break;
  398.  
  399.             case 14:
  400.             priority =  15;
  401.             basepri = priority;
  402.             break;
  403.  
  404.             case 15:
  405.             priority =  20;
  406.             basepri = priority;
  407.             break;
  408.             }
  409.             /* end of switch ( Priority itemnum ) */
  410.         break;
  411.  
  412.         case 3:
  413.         switch( itemnum ) {
  414.             case 0:
  415.             cmemsize = 0x000000;
  416.             enforcer = 0;
  417.             enforced = 0;
  418.             break;
  419.  
  420.             case 1:
  421.             cmemsize = 0x040000;
  422.             cschange = TRUE ;
  423.             break;
  424.  
  425.             case 2:
  426.             cmemsize = 0x080000;
  427.             cschange = TRUE ;
  428.             break;
  429.  
  430.             case 3:
  431.             cmemsize = 0x0c0000;
  432.             cschange = TRUE ;
  433.             break;
  434.  
  435.             case 4:
  436.             cmemsize = 0x100000;
  437.             cschange = TRUE ;
  438.             break;
  439.  
  440.             case 5:
  441.             cmemsize = 0x180000;
  442.             cschange = TRUE ;
  443.             break;
  444.  
  445.             case 6:
  446.             cmemsize = 0x200000;
  447.             cschange = TRUE ;
  448.             break;
  449.             }
  450.             /* end of switch ( Chip Size itemnum ) */
  451.         break;
  452.  
  453.         case 4:
  454.         switch( itemnum ) {
  455.             case 0:
  456.             cmembase = 0x000000;
  457.             if ( mode == TRUE )  {
  458.                 enforcer = TRUE;
  459.                 }
  460.             break;
  461.  
  462.             case 1:
  463.             cmembase = 0x040000;
  464.             break;
  465.  
  466.             case 2:
  467.             cmembase = 0x080000;
  468.             break;
  469.  
  470.             case 3:
  471.             cmembase = 0x0c0000;
  472.             break;
  473.  
  474.             case 4:
  475.             cmembase = 0x100000;
  476.             break;
  477.  
  478.             case 5:
  479.             cmembase = 0x180000;
  480.             break;
  481.  
  482.             case 6:
  483.             cmembase = 0xc00000;
  484.             break;
  485.  
  486.             case 7:
  487.             cmembase = 0xc40000;
  488.             break;
  489.  
  490.             case 8:
  491.             cmembase = 0xc80000;
  492.             break;
  493.  
  494.             case 9:
  495.             cmembase = 0xcc0000;
  496.             break;
  497.  
  498.             case 10:
  499.             cmembase = 0xd00000;
  500.             break;
  501.  
  502.             case 11:
  503.             cmembase = 0xd40000;
  504.             break;
  505.             }
  506.             /* end of switch ( Chip Addr itemnum ) */
  507.         break;
  508.  
  509.         case 5:
  510.         if (mode == WARPS)  mmode = TRUE ;
  511.         switch( itemnum ) {
  512.             case 0:
  513.             sfmemsize = 0x000000;
  514.             break;
  515.  
  516.             case 1:
  517.             sfmemsize = 0x040000;
  518.             break;
  519.  
  520.             case 2:
  521.             sfmemsize = 0x080000;
  522.             break;
  523.  
  524.             case 3:
  525.             sfmemsize = 0x0c0000;
  526.             break;
  527.  
  528.             case 4:
  529.             sfmemsize = 0x100000;
  530.             break;
  531.  
  532.             case 5:
  533.             sfmemsize = 0x180000;
  534.             break;
  535.  
  536.             case 6:
  537.             sfmemsize = 0x200000;
  538.             break;
  539.  
  540.             case 7:
  541.             sfmemsize = 0x300000;
  542.             break;
  543.  
  544.             case 8:
  545.             sfmemsize = 0x400000;
  546.             break;
  547.  
  548.             case 9:
  549.             sfmemsize = 0x600000;
  550.             break;
  551.  
  552.             case 10:
  553.             sfmemsize = 0x800000;
  554.             break;
  555.             }
  556.             /* end of switch ( SF Size itemnum ) */
  557.         break;
  558.  
  559.         case 6:
  560.         if (mode == WARPS)  mmode = TRUE ;
  561.         switch( itemnum ) {
  562.             case 0:
  563.             sfmembase = 0x200000;
  564.             break;
  565.  
  566.             case 1:
  567.             sfmembase = 0x240000;
  568.             break;
  569.  
  570.             case 2:
  571.             sfmembase = 0x280000;
  572.             break;
  573.  
  574.             case 3:
  575.             sfmembase = 0x2c0000;
  576.             break;
  577.  
  578.             case 4:
  579.             sfmembase = 0x300000;
  580.             break;
  581.  
  582.             case 5:
  583.             sfmembase = 0x400000;
  584.             break;
  585.  
  586.             case 6:
  587.             sfmembase = 0x500000;
  588.             break;
  589.  
  590.             case 7:
  591.             sfmembase = 0x600000;
  592.             break;
  593.  
  594.             case 8:
  595.             sfmembase = 0x700000;
  596.             break;
  597.  
  598.             case 9:
  599.             sfmembase = 0x800000;
  600.             break;
  601.  
  602.             case 10:
  603.             sfmembase = 0x900000;
  604.             break;
  605.  
  606.             case 11:
  607.             sfmembase = 0xc00000;
  608.             break;
  609.  
  610.             case 12:
  611.             sfmembase = 0xc40000;
  612.             break;
  613.  
  614.             case 13:
  615.             sfmembase = 0xc80000;
  616.             break;
  617.  
  618.             case 14:
  619.             sfmembase = 0xcc0000;
  620.             break;
  621.  
  622.             case 15:
  623.             sfmembase = 0xd00000;
  624.             break;
  625.             }
  626.             /* end of switch ( SF Addr itemnum ) */
  627.         break;
  628.  
  629.         case 7:
  630.         if (mode == WARPS)  mmode = TRUE ;
  631.         switch( itemnum ) {
  632.             case 0:
  633.             fmemsize = 0x000000;
  634.             break;
  635.  
  636.             case 1:
  637.             fmemsize = 0x040000;
  638.             break;
  639.  
  640.             case 2:
  641.             fmemsize = 0x080000;
  642.             break;
  643.  
  644.             case 3:
  645.             fmemsize = 0x0c0000;
  646.             break;
  647.  
  648.             case 4:
  649.             fmemsize = 0x100000;
  650.             break;
  651.  
  652.             case 5:
  653.             fmemsize = 0x200000;
  654.             break;
  655.  
  656.             case 6:
  657.             fmemsize = 0x300000;
  658.             break;
  659.  
  660.             case 7:
  661.             fmemsize = 0x400000;
  662.             break;
  663.  
  664.             case 8:
  665.             fmemsize = 0x500000;
  666.             break;
  667.  
  668.             case 9:
  669.             fmemsize = 0x600000;
  670.             break;
  671.  
  672.             case 10:
  673.             fmemsize = 0x700000;
  674.             break;
  675.  
  676.             case 11:
  677.             fmemsize = 0x800000;
  678.             break;
  679.  
  680.             case 12:
  681.             fmemsize = 0xa00000;
  682.             break;
  683.  
  684.             case 13:
  685.             fmemsize = 0xc00000;
  686.             break;
  687.  
  688.             case 14:
  689.             fmemsize = 0xe00000;
  690.             break;
  691.  
  692.             case 15:
  693.             fmemsize = 0x1000000;
  694.             break;
  695.             }
  696.             /* end of switch ( Fast Size itemnum ) */
  697.         break;
  698.  
  699.         case 8:
  700.         if (mode == WARPS)  mmode = TRUE ;
  701.         switch( itemnum ) {
  702.             case 0:
  703.             fmembase = 0x7f00000;
  704.             break;
  705.  
  706.             case 1:
  707.             fmembase = 0x7e00000;
  708.             break;
  709.  
  710.             case 2:
  711.             fmembase = 0x7d00000;
  712.             break;
  713.  
  714.             case 3:
  715.             fmembase = 0x7c00000;
  716.             break;
  717.  
  718.             case 4:
  719.             fmembase = 0x7a00000;
  720.             break;
  721.  
  722.             case 5:
  723.             fmembase = 0x7800000;
  724.             break;
  725.  
  726.             case 6:
  727.             fmembase = 0x7600000;
  728.             break;
  729.  
  730.             case 7:
  731.             fmembase = 0x7400000;
  732.             break;
  733.  
  734.             case 8:
  735.             fmembase = 0x7200000;
  736.             break;
  737.  
  738.             case 9:
  739.             fmembase = 0x7000000;
  740.             break;
  741.  
  742.             case 10:
  743.             fmembase = 0x9000000;
  744.             break;
  745.  
  746.             case 11:
  747.             fmembase = 0x8c00000;
  748.             break;
  749.  
  750.             case 12:
  751.             fmembase = 0x8800000;
  752.             break;
  753.  
  754.             case 13:
  755.             fmembase = 0x8400000;
  756.             break;
  757.  
  758.             case 14:
  759.             fmembase = 0x8200000;
  760.             break;
  761.  
  762.             case 15:
  763.             fmembase = 0x8000000;
  764.             break;
  765.             }
  766.             /* end of switch ( Fast Addr itemnum ) */
  767.         break;
  768.         }
  769.         /* end of switch ( menunum ) */
  770. }
  771.  
  772. void wrack_sploot() /* this subprogram cashes in the chips in bad times */
  773.     {
  774.     if (log != 0) {
  775.         if (log & SA) {
  776.             (void) FreeMem(oldcsum, (long)(sizeof(ULONG) * bars)) ;
  777.             log = log & CA ;
  778.             }
  779.         if (log & S8) {
  780.             (void) FreeMem(csum, (long)(sizeof(ULONG) * bars)) ;
  781.             log = log & C8 ;
  782.             }
  783.         if (log & S4)  {
  784.             (void) FreeMem(sizev, (long)(sizeof(long) * frags)) ;
  785.             log = log & C4 ;
  786.             }
  787.         if (log & S2)  {
  788.             (void) FreeMem(chunkv, (long)(sizeof(long) * frags)) ;
  789.             log = log & C2 ;
  790.             }
  791.         if (log & S1) {
  792.             (void) FreeMem(cell, (long)(sizeof(USHORT) * bars)) ;
  793.             log = log & C1 ;
  794.             }
  795.         frags = 0;
  796.         bars = 0;
  797.         }
  798. }
  799.  
  800. SetTimer(sec, micro, timermsg)
  801. ULONG sec, micro;
  802. struct IOStdReq *timermsg;
  803. /* This routine simply sets the timer to interrupt us after secs.micros */
  804. {
  805.     timermsg->io_Command = TR_ADDREQUEST;    /* add a new timer request */
  806.     timermsg->io_Actual = sec;    /* seconds */
  807.     timermsg->io_Length = micro;    /* microseconds */
  808.     SendIO((struct IORequest *)timermsg);   /* post a request to the timer */
  809. }
  810.  
  811. void cleanup() {
  812.     if (timerport) {
  813.         Wait(timerbit);
  814.         GetMsg(timerport);
  815.         CloseDevice((struct IORequest *)timermsg);
  816.         DeleteStdIO(timermsg);
  817.         DeletePort(timerport);
  818.         }
  819.     if (GfxBase)        CloseLibrary((struct Library *)GfxBase) ;
  820.     if (window)         CloseWindow(window) ;
  821.     if (IntuitionBase)  CloseLibrary((struct Library *)IntuitionBase) ;
  822.     wrack_sploot() ;
  823.     exit(AARRRGH) ;
  824. }
  825.  
  826. void inittimer()
  827. {
  828.     if(!(timerport = (struct MsgPort *)CreatePort(0L, 0L)))cleanup();
  829.     if(!(timermsg = (struct IOStdReq *)CreateStdIO(timerport)))cleanup();
  830.     if (OpenDevice((UBYTE *)TIMERNAME, UNIT_VBLANK, (struct IORequest *)timermsg, 0L))cleanup();
  831.  
  832.     timerbit = 1L << timerport->mp_SigBit ;
  833.     SetTimer(1L, 0L, timermsg); /* set for first message */
  834. }
  835.  
  836. void handle_NEWSIZE() /* short term allocations cashed in then realloc'd */
  837.     {                 /* when user hits gadget but doesn't resize window */
  838.     if (log & SA)  {
  839.         (void) FreeMem(oldcsum, (long)(sizeof(ULONG) * bars)) ;
  840.         log = log & CA ;
  841.         }
  842.     if (log & S8)  {
  843.         (void) FreeMem(csum, (long)(sizeof(ULONG) * bars)) ;
  844.         log = log & C8 ;
  845.         }
  846.     if (log & S1)  {
  847.         (void) FreeMem(cell, (long)(sizeof(USHORT) * bars)) ;
  848.         log = log & C1 ;
  849.     barh = window->Height - SIZEGAD - DRAGBAR ;  /* recalculate height */
  850.     barb = window->Height - SIZEGAD - 1 ; /* get new bar base position */
  851.     bars = barh + 1 ;       /* number of storage frames to be reserved */
  852.     if ((cell = (USHORT *)AllocMem((long)sizeof(USHORT) * bars,
  853.                                     MEMF_PUBLIC)) != 0L ) log = log | S1;
  854.     if ((csum = (ULONG *)AllocMem((long)sizeof(ULONG) * bars,
  855.                                     MEMF_PUBLIC)) != 0L ) log = log | S8;
  856.     if ((oldcsum = (ULONG *)AllocMem((long)sizeof(ULONG) * bars,
  857.                                     MEMF_PUBLIC)) != 0L ) log = log | SA;
  858.     if (log != SOK)  {      /* bail out if we didn't get an allocation */
  859.         wrack_sploot() ;
  860.         things_are_cool = FALSE ;     /* tell _main that we're leaving */
  861.         }
  862.     e_text.TopEdge = barb + BORDER ;        /* set the E text position */
  863.     intsig = FALSE ;
  864.     }
  865. }
  866.  
  867. void handle_MESSAGES()  {
  868.     unsigned long class;
  869.     unsigned int code, qual;
  870. #ifdef TALKTOREXX
  871.     /*    Wait ( (1L << window->UserPort->mp_SigBit) | rexxbit) ;
  872.      *    Gosh, folks, if we do this, we get nothing else done.
  873.      *    So we have to figure out how to drop in and look for Intuition
  874.      *    and Rexx messages without having to hang around.  In previous
  875.      *    versions of this program we just crashed through the door and
  876.      *    attempted to pick up messages.  Methinks these days that's not
  877.      *    such a good idea.  Better look for a signal bit first.  Any sig
  878.      *    bit will do, we just need one to help our interaction with Exec
  879.      *    to stay atomic.
  880.      */
  881.  
  882.     if ( ( 1L << window->UserPort->mp_SigBit ) | rexxbit );  {
  883.        dispRexxPort() ;
  884. #else
  885.     if ( 1L << window->UserPort->mp_SigBit ) ;  {
  886. #endif
  887.        while ((NewMessage=(struct IntuiMessage *)GetMsg(window->UserPort))
  888.                                                                 != 0L) {
  889.            class = NewMessage->Class ;
  890.            code = NewMessage->Code ;
  891.            qual = NewMessage->Qualifier ;
  892.            ReplyMsg ;
  893.            ticker = 0 ;        /* cut short the timer to expedite service */
  894.            switch( class ) {
  895.                case MENUPICK:
  896.                handle_MENUPICK( class, code ) ;    /* do menus ASAP */
  897.                break ;
  898.  
  899.                case NEWSIZE:
  900.                intsig = TRUE ;                     /* resize when done here */
  901.                break ;
  902.                }
  903.            }
  904.         }
  905. }
  906.  
  907. void memmometer()                /* this subprogram draws the bar graphs */
  908.     {
  909.     long i;
  910.     long y;
  911.  
  912.     (void) handle_MESSAGES() ;  /* go see if the user wants anything */
  913.     i = 0 ;
  914.     while ((i < barh) && (intsig == FALSE)) {
  915.         y = barb - i ;
  916.         SetAPen(window->RPort, (long)cell[i]);
  917.         Move(window->RPort, xl, y);
  918.         Draw(window->RPort, xr, y);
  919.         i++ ;
  920.         }
  921. }
  922.  
  923. void shake()    /* this subprogram slings down the mercury column */
  924.     {
  925.     int i;
  926.  
  927.     for (i = 0; i < barh; i++)  {
  928.         cell[i] = WHTP ;
  929.         }
  930. }
  931.  
  932. void lockout()  /* this subprogram renders a whole column in border colors */
  933.     {
  934.     (void) handle_MESSAGES() ;        /* go see if the user wants anything */
  935.     if (intsig == FALSE)  {
  936.         SetAPen(window->RPort, BORP) ;          /* set in the border color */
  937.         RectFill(window->RPort, xl, (barb - barh + 1), xr, barb) ; /* fill */
  938.         }
  939. }
  940.  
  941. void updatewarps( wf, membase, memseg )  /* this subprogram finds changes */
  942. short wf;
  943. long membase, memseg ;
  944.     {
  945.     register long i ;
  946.     register ULONG r ;
  947.     register ULONG delta ;
  948.     register ULONG *a ;
  949.  
  950.     if (memseg == 0) {
  951.         (void) lockout() ;
  952.         return ;
  953.         }
  954.     else (void) shake() ;
  955.  
  956.     delta = (ULONG)(memseg & EVENMASK) ;  /* try to avoid odd address trap */
  957.     r = (ULONG)(membase & EVENMASK) ;     /* prefer wrong address to death */
  958.     for (i = 0; i < barh; i++)  {
  959.         csum[i] = 0 ;
  960.         }
  961.     for (i = 0; i < barh; i++)  {
  962.         for (a = (ULONG *)r; a < (ULONG *)(r + delta); a++)  {
  963.             csum[i] ^= *a ;
  964.             }
  965.         if (oldcsum[i] != 0)  cell[i] ^= 4L ;         /* enters with pens  */
  966.         if (csum[i] == oldcsum[i])  cell[i] &= 4L ;   /* all on, condition */
  967.         if (csum[i] == 0)  cell[i] ^= 6L ;            /* detected clears a */
  968.         if (oldcsum[i] == 0xffffffff) cell[i] = 6L ;  /* pen; at the end a */
  969.         if (csum[i] == 0xffffffff)  cell[i] = 4L ;    /* logical true sets */
  970.         oldcsum[i] = csum[i] ;                        /* a pen not yet set */
  971.         r += delta ;
  972.         }
  973.     (void) memmometer();
  974. }
  975.  
  976. void updatescreen( wf, membase, memseg )
  977. short wf;
  978. long membase, memseg;
  979.     {
  980.     register long size ;
  981.     register struct MemHeader *hdr ;
  982.     register struct MemChunk *chunk ;
  983.     extern struct ExecBase *SysBase ;
  984.     register long *which ;                /* active memlist chunk pointer */
  985.     register long newlimit ;  /* number of chunks, incl 1 null chunk, + 1 */
  986.     register long newfrags ;  /* number of chunks, incl null chunks, + 1  */
  987.     long newsize ;  /* size of next request for chunkv/sizev memory, + 1  */
  988.     int i, j, k, l ;
  989.     int length ;       /* length is number of chunks to be processed, + 1 */
  990.     BOOL cf, nf ;      /* cf is "chip flag" nf is "null chunk found" flag */
  991.  
  992.     if (memseg == 0) {
  993.         (void) lockout() ;
  994.         return;
  995.         }
  996.     else (void) shake() ;
  997.  
  998.     for (i = 0; i < 3; i++) {
  999.         chip[i] = 0;
  1000.         fast[i] = 0;
  1001.         }
  1002.     for (i = 0; i < frags; i++) {
  1003.         chunkv[i] = 0;
  1004.         sizev[i] = 0;
  1005.         }
  1006.     newfrags = 0 ;
  1007.     newlimit = 0 ;
  1008.     nf = FALSE;
  1009.     Forbid() ;
  1010.     hdr = (struct MemHeader *) SysBase->MemList.lh_Head ;
  1011.     while (hdr->mh_Node.ln_Succ) {
  1012.         if (hdr->mh_Attributes & MEMF_CHIP) {
  1013.             which = chip ;
  1014.             cf = TRUE;
  1015.             }
  1016.         else {
  1017.             which = fast ;
  1018.             cf = FALSE;
  1019.             }
  1020.         if (((cf == TRUE) && (wf == 0)) || ((cf == FALSE) && (wf > 0)))  {
  1021.             for (chunk = hdr->mh_First; chunk; chunk = chunk->mc_Next) {
  1022.                 if (which[1] < frags)  chunkv[which[1]++] = (unsigned long)chunk ;
  1023.                 size = chunk->mc_Bytes ;
  1024.                 if (which[2] < frags)  sizev[which[2]++] = (unsigned long)size;
  1025.                 *which += size ;
  1026.                 if (nf == FALSE)  {
  1027.                     newlimit++ ;
  1028.                     if (chunkv[newfrags] == NULL)  {
  1029.                         nf = TRUE;
  1030.                         }
  1031.                     }
  1032.                 newfrags++ ;
  1033.             }
  1034.         }
  1035.         hdr = (struct MemHeader *)hdr->mh_Node.ln_Succ ;
  1036.         }
  1037.     Permit() ;
  1038.     length = frags ;
  1039.     if (newlimit < frags)  length = newlimit ;
  1040.     for (i = 0; i < length; i++)  {
  1041.         chunkv[i] -= membase;   /* chunkv is now array offset from base   */
  1042.         sizev[i] += chunkv[i];  /* and sizev is now address of array top  */
  1043.         chunkv[i] = chunkv[i] / memseg;  /* this is the number of pixels  */
  1044.         sizev[i] = sizev[i] / memseg;       /* and this is the top pixel  */
  1045.         if (chunkv[i] < 0) chunkv[i] = 0 ;  /* we do some bounds checking */
  1046.         if (sizev[i] < 0) sizev[i] = 0 ;
  1047.         if (chunkv[i] >= barh) chunkv[i] = barh - 1 ;
  1048.         if (sizev[i] >= barh) sizev[i] = barh - 1 ;
  1049.         if (sizev[i] - chunkv[i] < 0)  sizev[i] = chunkv[i] ;
  1050.         j = chunkv[i] ; /* from now on it will be less confusing if */
  1051.         k = sizev[i] ;  /* we assign some variables for this stuff  */
  1052.         if (sizev[i] - chunkv[i] == 0)  {
  1053.             cell[j] &= BAKP ;
  1054.             }
  1055.         else  {
  1056.             for (l = j; l < k; l++)  {
  1057.                 cell[l] &= HLTP ;
  1058.                 }
  1059.             }
  1060.         }
  1061.     (void) memmometer();
  1062.     newsize = frags ;
  1063.     while (newsize < newlimit)  {
  1064.         newsize += EXTENSION ;
  1065.         }
  1066.     if (newlimit > frags)  {
  1067.         (void) FreeMem(chunkv, (long)(sizeof(long) * frags));
  1068.         if ((chunkv = (unsigned long *)AllocMem((long)sizeof(long) * newsize,
  1069.                                         MEMF_PUBLIC)) == 0L )  {
  1070.             log = log & C2 ;
  1071.             }
  1072.         (void) FreeMem(sizev, (long)(sizeof(long) * frags));
  1073.         if ((sizev = (unsigned long *)AllocMem((long)sizeof(long) * newsize,
  1074.                                         MEMF_PUBLIC)) == 0L ) {
  1075.             (void) FreeMem(chunkv, (long)(sizeof(long) * newsize));
  1076.             log = log & C4 ;
  1077.             }
  1078.         if (log != SOK)  {
  1079.             wrack_sploot() ;
  1080.             things_are_cool = FALSE ;
  1081.             }
  1082.         else frags = newsize ;
  1083.         }
  1084. }
  1085.  
  1086. main(argc, argv)
  1087. int argc ;
  1088. char *argv[] ;
  1089. {
  1090.     static struct IntuiText bodyText0 =
  1091.         {BAKP, SHAP, JAM2, 58, 10, NULL, NULL, NULL};
  1092.     static struct IntuiText bodyText1 =
  1093.         {BAKP, SHAP, JAM2, 42, 20, NULL, NULL, NULL};
  1094.     static struct IntuiText bodyText2 =
  1095.         {BAKP, SHAP, JAM2, 50, 30, NULL, NULL, NULL};
  1096.     static struct IntuiText positiveText =
  1097.         {BAKP, SHAP, JAM2, 7, 3, NULL, NULL, NULL};
  1098.     static struct IntuiText negativeText =
  1099.         {BAKP, SHAP, JAM2, 7, 3, NULL, NULL, NULL};
  1100.     struct IntuiMessage *NewMessage;
  1101.     ULONG class;
  1102.     USHORT code;
  1103.     ULONG wakeupbits;
  1104.     long syspri;
  1105.     char *nptr;
  1106.     struct Task *mmtcb;
  1107.     char oldpri;
  1108.     int t;
  1109.     int i;
  1110.  
  1111. #ifdef TALKTOREXX
  1112. /*
  1113.  *  Local variables for rexx
  1114.  */
  1115.     int x;
  1116.     char mmi[4] = "mm0";
  1117.     char four[2] = "4";
  1118. #endif
  1119.     USHORT colflags;     /* keeps track of column positions and counts */
  1120.     USHORT left;         /* left   column, left edge */
  1121.     USHORT middle;       /* middle column, left edge */
  1122.     USHORT right;        /* right  column, left edge */
  1123.     USHORT barw;         /* width of each mercury column */
  1124.     USHORT wf;           /* memmometer window current column number */
  1125.     long cmemseg;
  1126.     long sfmemseg;
  1127.     long fmemseg;
  1128.     long membase;
  1129.     long memseg;
  1130.     long memsize;
  1131.  
  1132.     bodyText0.IText = (UBYTE *) "WARNING! CRASH POSSIBLE";
  1133.     bodyText1.IText = (UBYTE *) "MENU MEMORY SELECTIONS MUST";
  1134.     bodyText2.IText = (UBYTE *) "REFERENCE EXISTING MEMORY";
  1135.     bodyText0.NextText = &bodyText1;
  1136.     bodyText1.NextText = &bodyText2;
  1137.     positiveText.IText = (UBYTE *) "Risk It";
  1138.     negativeText.IText = (UBYTE *) "Retreat";
  1139.  
  1140.     log = 0 ;
  1141.     if ((cell = (USHORT *)AllocMem((long)sizeof(USHORT) * BARS,
  1142.                                         MEMF_PUBLIC)) != 0L ) log = log | S1;
  1143.     if ((chunkv = (ULONG *)AllocMem((long)sizeof(ULONG) * STARTVAL,
  1144.                                         MEMF_PUBLIC)) != 0L ) log = log | S2;
  1145.     if ((sizev = (ULONG *)AllocMem((long)sizeof(ULONG) * STARTVAL,
  1146.                                         MEMF_PUBLIC)) != 0L ) log = log | S4;
  1147.     if ((csum = (ULONG *)AllocMem((long)sizeof(ULONG) * BARS,
  1148.                                         MEMF_PUBLIC)) != 0L ) log = log | S8;
  1149.     if ((oldcsum = (ULONG *)AllocMem((long)sizeof(ULONG) * BARS,
  1150.                                         MEMF_PUBLIC)) != 0L ) log = log | SA;
  1151.     if (log != SOK)  {
  1152.         wrack_sploot() ;
  1153.         exit(AARRRGH) ;
  1154.         }
  1155.     if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary(
  1156.             (UBYTE *)"intuition.library",33L)) != NULL &&
  1157.             (window=OpenWindow(&newwindow)) != NULL)  {
  1158.         if ((GfxBase = (struct GfxBase *)OpenLibrary(
  1159.                 (UBYTE *)"graphics.library", 0L)) != NULL)  { 
  1160.             (void) initmenus();
  1161.             /* rp = window->RPort ; */
  1162.             inittimer();
  1163.             wf = 0;
  1164.             enforcer = FALSE ;  /* these are WARPS mode flags that let us  */
  1165.             enforced = FALSE ;  /* know that we have to adjust cmembase &  */
  1166.             pmchange = FALSE ;  /* cmemsize to avoid alarming the enforcer */
  1167.             cschange = FALSE ;  /* the change flags track the menu changes */
  1168.             mmode = FALSE ;
  1169.             mode = p_mode ;
  1170.             delayval = p_rate ;
  1171.             priority = p_priority ;
  1172.             basepri = priority ;
  1173.             syspri = priority ;
  1174.             nptr = NULL ;
  1175.             mmtcb = FindTask( (UBYTE *)nptr ) ;
  1176.             oldpri = SetTaskPri( mmtcb, syspri ) ;
  1177.             if (p_chip < 0)  p_chip = 0 ;
  1178.             cmemsize = p_chip << 10 ;
  1179.             p_chip = cmemsize ;
  1180.             if (p_chipa < 0)  p_chipa = 0 ;
  1181.             cmembase = p_chipa << 10 ;
  1182.             p_chipa = cmembase ;
  1183. #ifndef TALKTOREXX
  1184.             if ((cmembase == 0) && (mode == WARPS))  {
  1185.                cmembase = 0x400 ;
  1186.                if (cmemsize > 400)  cmemsize -= 0x400 ;
  1187.                enforced = TRUE ;
  1188.                }
  1189. #endif
  1190.             if (p_sf < 0)  p_sf = 0 ;
  1191.             sfmemsize = p_sf << 10 ;
  1192.             p_sf = sfmemsize ;
  1193.             if (p_sfa < 0) p_sfa = 0 ;
  1194.             sfmembase = p_sfa << 10 ;
  1195.             p_sfa = sfmembase ;
  1196.             if (p_fast < 0)  p_fast = 0 ;
  1197.             if (p_fast >= 256) fmemsize = p_sf << 10 ;
  1198.             else fmemsize = p_fast << 20 ;
  1199.             p_fast = fmemsize ;
  1200.             fmembase = 1 << 27 ;
  1201.             if (p_fasta > 0)  fmembase = (p_fasta << 27) ;
  1202.             else if (p_fasta < 0)  {
  1203.                 fmembase = 0x8000000 - ((-1 * p_fasta) << 20) ;
  1204.                 }
  1205.             p_fasta = fmembase ;
  1206. #ifdef TALKTOREXX
  1207. /*
  1208.  *   For rexx, open up a Rexx port, and send out the first command,
  1209.  *   if there was one; no reason not to send it out asynchronously.
  1210.  */
  1211.             refrshpre = FALSE ;
  1212.             while ( ( rexxbit == 0 ) && ( mmi[2] <= four[0] ) ){
  1213.                mmi[2]++ ;
  1214.                rexxbit = upRexxPort(mmi, rcl, NULL, &disp) ;
  1215.                }
  1216.             firstcommand[0] = 0 ;
  1217.             for (x=1; x<argc; x++) {
  1218.                strcat(firstcommand, argv[x]) ;
  1219.                strcat(firstcommand, " ") ;
  1220.                }
  1221.             if (firstcommand[0]) {
  1222.                asyncRexxCmd(firstcommand) ;
  1223.                }
  1224. #endif
  1225. /*
  1226.  *   Below is main's contained loop; we stay in it until we're told to quit.
  1227.  */
  1228.             while (things_are_cool == TRUE) {
  1229.  
  1230. #ifdef TALKTOREXX
  1231. /*
  1232.  *   Update rexx menu presets here.  No Mercy.  Except for our arexx function
  1233.  *   pre-check with respect to range, what user asks for is what user gets.
  1234.  *   To avoid objection by the enforcer, base addresses need to be above 1K
  1235.  *   for the WARPS mode.  All memory specifiers are interpreted directly as
  1236.  *   signed 32-bit values.
  1237.  */
  1238.                 if (refrshpre == TRUE)  {
  1239.                     chgflag = TRUE ;
  1240.                     delayval = p_rate ;
  1241.                     priority = p_priority ;
  1242.                     basepri = priority ;
  1243.                     syspri = priority ;
  1244.                     nptr = NULL ;
  1245.                     mmtcb = FindTask( (UBYTE *)nptr ) ;
  1246.                     oldpri = SetTaskPri( mmtcb, syspri ) ;
  1247.                     cmemsize = p_chip ; /* user can set this to anything */
  1248.                     cmembase = p_chipa ;/* we allow any possible address */
  1249.                     mode = p_mode ;     /* & user pays funeral expenses! */
  1250.                     sfmemsize = p_sf ;
  1251.                     sfmembase = p_sfa ;
  1252.                     fmemsize = p_fast ;
  1253.                     fmembase = p_fasta ;
  1254.                     refrshpre = FALSE ;
  1255.                     }
  1256. #endif
  1257.                 if (chgflag != 0)  {
  1258.                     chgflag = 0 ;
  1259.                     colflags = 0 ;
  1260.                     if (cmemsize != 0)  colflags = colflags | (1 << 0) ;
  1261.                     if (sfmemsize != 0)  colflags = colflags | (1 << 1) ;
  1262.                     if (fmemsize != 0)  colflags = colflags | (1 << 2) ;
  1263.                     switch ( colflags ) {
  1264.                         case 0:  /* NO SELECTION */
  1265.                         barw = (WINW - (2 * BORDER)) - 1 ;
  1266.                         left = LEFT ;
  1267.                         middle = 0 ;
  1268.                         right = 0 ;
  1269.                         f_text.FrontPen = BAKP ;
  1270.                         break ;
  1271.  
  1272.                         case 1:  /* CHIP ONLY */
  1273.                         barw = (WINW - (2 * BORDER)) - 1 ;
  1274.                         left = LEFT ;
  1275.                         middle = 0 ;
  1276.                         right = 0 ;
  1277.                         f_text.FrontPen = BAKP ;
  1278.                         break ;
  1279.  
  1280.                         case 2:  /* SF ONLY */
  1281.                         barw = (WINW - (2 * BORDER)) - 1 ;
  1282.                         left = 0 ;
  1283.                         middle = LEFT ;
  1284.                         right = 0 ;
  1285.                         f_text.FrontPen = HLTP ;
  1286.                         break ;
  1287.  
  1288.                         case 3:  /* CHIP & SF */
  1289.                         barw = ((WINW - (2 * BORDER)) / 2 ) - 1 ;
  1290.                         left = LEFT ;
  1291.                         middle = (left + barw + 1) ;
  1292.                         right = 0 ;
  1293.                         f_text.FrontPen = HLTP ;
  1294.                         break ;
  1295.  
  1296.                         case 4:  /* FAST ONLY */
  1297.                         barw = (WINW - (2 * BORDER)) - 1 ;
  1298.                         left = 0 ;
  1299.                         middle = 0;
  1300.                         right = LEFT ;
  1301.                         f_text.FrontPen = BLUP ;
  1302.                         break ;
  1303.  
  1304.                         case 5:  /* CHIP & FAST */
  1305.                         barw = ((WINW - (2 * BORDER)) / 2 ) - 1 ;
  1306.                         left = LEFT ;
  1307.                         middle = 0 ;
  1308.                         right = (left + barw + 1) ;
  1309.                         f_text.FrontPen = BLUP ;
  1310.                         break ;
  1311.  
  1312.                         case 6:  /* SF & FAST */
  1313.                         barw = ((WINW - (2 * BORDER)) / 2 ) - 1 ;
  1314.                         left = 0 ;
  1315.                         middle = LEFT ;
  1316.                         right = (middle + barw + 1) ;
  1317.                         f_text.FrontPen = CYNP ;
  1318.                         break ;
  1319.  
  1320.                         case 7:  /* CHIP & SF & FAST */
  1321.                         barw = ((WINW - (2 * BORDER)) / 3 ) - 1 ;
  1322.                         left = LEFT ;
  1323.                         middle = (left + barw + 1) ;
  1324.                         right = (middle + barw + 1) ;
  1325.                         f_text.FrontPen = CYNP ;
  1326.                         break ;
  1327.                         }  /* end of switch ( colflags ) */
  1328.                     }  /* end of if ( chgflag ) */
  1329.                 if (mmode == TRUE && ((sfmemsize != 0) ||
  1330.                                       (fmemsize != 0)))  {
  1331.                     /* Keep your eyes open here.  If we get a negative    */
  1332.                     /* response from the requester, that means either the */
  1333.                     /* user retreated, or a no-requester function such as */
  1334.                     /* noreq or KillReq has selected the negative option. */
  1335.                     /* If such functions select the positive option they  */
  1336.                     /* force acceptance of the crash risk for Warps mode. */
  1337.  
  1338.                     mode = AutoRequest(window, &bodyText0, &positiveText,
  1339.                                &negativeText, 0L, 0L, 319L, 79L) ;
  1340.                     if (mode == FALSE)  {      
  1341.                         sfmemseg = 0 ;         /* user Retreat selection  */
  1342.                         sfmemsize = 0 ;        /* results in execution of */
  1343.                         fmemseg = 0 ;          /* this code segment which */
  1344.                         fmemsize = 0 ;         /* resets to safer values  */
  1345.                         }
  1346.                     }
  1347.                 if (pmchange == TRUE)  {
  1348.                     if (mmode == TRUE)  enforcer = TRUE ;
  1349.                     else if (mode == FRAGS)  {
  1350.                         if ((cmembase = 0x400) && (enforced == TRUE)) {
  1351.                             cmembase = 0 ;
  1352.                             if (cmemsize > 0)  cmemsize += 0x400 ;
  1353.                             }
  1354.                         enforcer = FALSE ;
  1355.                         enforced = FALSE ;
  1356.                         }
  1357.                     pmchange = FALSE ;
  1358.                     }
  1359.                 if (mmode == TRUE)  {
  1360.                     mode = WARPS ;
  1361.                     mmode = FALSE ;
  1362.                     }
  1363.                 if (cschange == TRUE)  {
  1364.                     cschange = FALSE ;
  1365.                     if (mode == WARPS)  {
  1366.                         enforcer = TRUE ;
  1367.                         enforced = FALSE ;
  1368.                         }
  1369.                     }
  1370.                 if (enforcer == TRUE)  {
  1371.                     if (cmembase == 0)  cmembase = 0x400 ;
  1372.                     if (enforced == FALSE)  {
  1373.                         if (cmemsize > 0x400)  cmemsize -= 0x400 ;
  1374.                         enforced = TRUE ;
  1375.                         }
  1376.                     enforcer = FALSE ;
  1377.                     }
  1378.                 cmemseg = cmemsize / barh ;
  1379.                 sfmemseg = sfmemsize / barh ;
  1380.                 fmemseg = fmemsize / barh ;
  1381.                 switch ( wf ) {
  1382.                     case 0:
  1383.                     xl = left ;
  1384.                     membase = cmembase ;
  1385.                     memsize = cmemsize ;
  1386.                     memseg = cmemseg ;
  1387.                     break ;
  1388.  
  1389.                     case 1:
  1390.                     xl = middle ;
  1391.                     membase = sfmembase ;
  1392.                     memsize = sfmemsize ;
  1393.                     memseg = sfmemseg ;
  1394.                     break ;
  1395.  
  1396.                     case 2:
  1397.                     xl = right ;
  1398.                     membase = fmembase ;
  1399.                     memsize = fmemsize ;
  1400.                     memseg = fmemseg ;
  1401.                     break ;
  1402.                     }  /* end of switch ( wf ) */
  1403.                 xr = xl + barw ;
  1404.                 if (xl != 0)  {
  1405.                     if (intsig == TRUE)  {
  1406.                         handle_NEWSIZE() ;
  1407.                         }
  1408.                     if (mode == WARPS)  {
  1409.                         (void) updatewarps( wf, membase, memseg ) ;
  1410.                         e_text.FrontPen = WHTP ;
  1411.                         }
  1412.                     if (mode == FRAGS)  {
  1413.                         (void) updatescreen( wf, membase, memseg ) ;
  1414.                         e_text.FrontPen = BAKP ;
  1415.                         }
  1416.                     }
  1417.                 if (syspri != priority)  {
  1418.                     syspri = priority ;
  1419.                     nptr = NULL;
  1420.                     mmtcb = FindTask( (UBYTE *)nptr ) ;
  1421.                     oldpri = SetTaskPri( mmtcb, syspri ) ;
  1422.                     }
  1423.                 if (wf == 2)  {
  1424.                     PrintIText(window->RPort,&f_text,RTEXT,0L) ;
  1425.                     while ( ticker > 0 )  {
  1426.                         wakeupbits = Wait(timerbit) ;
  1427.                         if (wakeupbits & timerbit)  {
  1428.                             GetMsg(timerport);
  1429.                             SetTimer(0L, TMARK, timermsg);
  1430.                             }
  1431.                         /* quick like, go see if the user wants anything */
  1432.                         (void) handle_MESSAGES() ;
  1433.                         ticker-- ;
  1434.                         }
  1435.                     ticker = delayval * TICKIES ;
  1436.                     }
  1437.                 wf++ ;
  1438.                 if (wf >= 3)  wf = 0 ;
  1439.                 if (intsig == TRUE)  {
  1440.                     handle_NEWSIZE() ;
  1441.                     }
  1442.                 } /* end of while ( things_are_cool) */
  1443.  
  1444.             if (timerport) {
  1445.                 Wait(timerbit);
  1446.                 GetMsg(timerport);
  1447.                 CloseDevice((struct IORequest *)timermsg);
  1448.                 DeleteStdIO(timermsg);
  1449.                 DeletePort(timerport);
  1450.                 }
  1451.  
  1452. #ifdef TALKTOREXX
  1453. /*
  1454.  *   With Rexx, we need to bring the port down.
  1455.  */
  1456.             dnRexxPort() ;
  1457. #endif
  1458.             if (GfxBase)    CloseLibrary((struct Library *)GfxBase) ;
  1459.             }
  1460.         if (window)         CloseWindow(window) ;
  1461.         if (IntuitionBase)  CloseLibrary((struct Library *)IntuitionBase) ;
  1462.         }
  1463.     wrack_sploot() ;
  1464. exit(0L) ;
  1465. }
  1466.  
  1467. #ifdef TALKTOREXX
  1468. /*
  1469.  *   Now we get into the actual code necessary for our REXX port; functions
  1470.  *   that do the real work.  Note that this program was not structured very
  1471.  *   nicely for Rexx; Tom earlier wrote some of these functions, particularly
  1472.  *   the argument parser and argument evaluator.  I did the menu functions.
  1473.  *   Many programs have these subroutines already in place; they are called
  1474.  *   as part of the event loop.  This program, however, just has one big
  1475.  *   switch statement with different actions.  It's definitely an early Amiga
  1476.  *   class program, my fault, of course . . .
  1477.  *
  1478.  *   First, the locals.
  1479.  */
  1480. long args[4] ;                 /* what args did we see to this function? */
  1481. int parsed ;                   /* was argument parsing successful? */
  1482. int userreplied ;              /* has current message been replied to yet? */
  1483. /*
  1484.  *   This function takes a pointer to a pointer to a string, grabs the
  1485.  *   next number, returns it, and advances the pointer to the string to
  1486.  *   point after the number.
  1487.  */
  1488. long getnm(where)
  1489. char **where ;
  1490. {
  1491.    register char *p = *where ;
  1492.    register long val = 0 ;
  1493.    int gotone = 0 ;
  1494.    long sign = 1 ;
  1495.  
  1496.    while (*p <= '-' && *p) {
  1497.       if (*p == '-')  {  /* look for a unary negative operator */
  1498.          sign = -1 ;
  1499.          }
  1500.       p++ ;
  1501.       }
  1502.    while ('0' <= *p && *p <= '9') {
  1503.       gotone = 1 ;
  1504.       val = 10 * val + *p++ - '0' ;
  1505.    }
  1506.    val = sign * val ;
  1507.    if (gotone == 0)
  1508.       parsed = 0 ;
  1509.    *where = p ;
  1510.    return(val) ;
  1511. }
  1512. /*
  1513.  *   This function trys to find `n' numeric arguments in the command
  1514.  *   string, and stuffs them into the args array.
  1515.  */
  1516. void parseargs(p, n)
  1517. char *p ;
  1518. int n ;
  1519. {
  1520.    register int i ;
  1521.  
  1522.    while (*p > ' ' && *p)
  1523.       p++ ;
  1524.    for (i=0; i<n; i++)
  1525.       args[i] = getnm(&p) ;
  1526. }
  1527. /*
  1528.  *   This is our main dispatch function.  We check to make sure a Window
  1529.  *   currently exists.  Then we call our handler function.  If our handler
  1530.  *   replied, we return a 1 to indicate that. If the parse and everything
  1531.  *   else was successful, we return a 0. Otherwise, we return a failure
  1532.  *   code of 20 to indicate that the arguments were messed up.
  1533.  */
  1534. void disp(msg, dat, p)
  1535. register struct RexxMsg *msg ;
  1536. register struct rexxCommandList *dat ;
  1537. char *p ;
  1538. {
  1539.    parsed = 1 ;
  1540.    if (window) {
  1541.       userreplied = 0 ;
  1542.       ((long (*)())(dat->userdata))(msg, p) ;
  1543.       if (! parsed)  replyRexxCmd(msg, (long)parsed, 0L, NULL) ;
  1544.       else  {
  1545.          refrshpre = TRUE ; /* Mark Rexx request to change a preset variable */
  1546.          DoCheckMenus() ;   /* Remove menu checkmarks invalidated via these  */
  1547.          dechecked = 0 ;    /*  function calls, fix re-validated check marks */
  1548.          rechecked = 0 ;
  1549.          }
  1550.       return ;
  1551.    }
  1552.    replyRexxCmd(msg, 20L, 10L, NULL) ;
  1553. }
  1554. /*
  1555.  *   This handler brings the MemMometer window to front.
  1556.  */
  1557. void rexxfront(msg, p)
  1558. struct RexxMsg *msg ;
  1559. char *p ;
  1560. {
  1561.    WindowToFront(window) ;
  1562. }
  1563. /*
  1564.  *   This handler pushes the MemMometer window to back.
  1565.  */
  1566. void rexxback(msg, p)
  1567. struct RexxMsg *msg ;
  1568. char *p ;
  1569. {
  1570.    WindowToBack(window) ;
  1571. }
  1572. /*
  1573.  *   This handler sets the Quit boolian.
  1574.  */
  1575. void rexxquit(msg, p)
  1576. struct RexxMsg *msg ;
  1577. char *p ;
  1578. {
  1579.    things_are_cool = FALSE ;
  1580. }
  1581. /*
  1582.  *   This handler sets the MemMometer p_mode preset boolian.  The boolian
  1583.  *   should be set either to FRAGS or to WARPS.  Note that for safety reasons,
  1584.  *   this is done clandestinely, namely, any value other than "42" (WARPS) or
  1585.  *   "0" (FRAGS) produces a Rexx error message.
  1586.  */
  1587. void rexxmode(msg, p)
  1588. struct RexxMsg *msg ;
  1589. char *p ;
  1590. {
  1591.    parseargs(p, 1) ;
  1592.    if ( args[0] == 0  )  {
  1593.       p_mode = FRAGS ;
  1594.       dechecked |= 0x1 ;
  1595.       rechecked = 1 ;
  1596.       }
  1597.    else if ( args[0] == 42 )  {
  1598.       p_mode = WARPS ;
  1599.       dechecked |= 0x1 ;
  1600.       rechecked = 2 ;
  1601.       }
  1602.    else parsed = 0 ;
  1603. }
  1604. /*
  1605.  *   This handler sets the between-scans delay time preset variable.
  1606.  */
  1607. void rexxrate(msg, p)
  1608. struct RexxMsg *msg ;
  1609. char *p ;
  1610. {
  1611.    parseargs(p, 1) ;
  1612.    if ( ( args[0] > 0 ) && ( args[0] <= 60 ) )  {
  1613.       p_rate = args[0] ;
  1614.       dechecked |= 0x2 ;
  1615.       }
  1616.    else parsed = 0 ;
  1617.  
  1618. }
  1619. /*
  1620.  *   This handler sets the priority preset variable.  Note that the range
  1621.  *   is greater than that allowed by the menu items.  Be careful.  Positive
  1622.  *   values greater than 20 will lock everything out so devestatingly that
  1623.  *   you'll have to reboot to get the system back to life.
  1624.  */
  1625. void rexxpriority(msg, p)
  1626. struct RexxMsg *msg ;
  1627. char *p ;
  1628. {
  1629.    parseargs(p, 1) ;
  1630.    if ( ( args[0] < 128 ) && ( args[0] > -128 ) )  {
  1631.       p_priority = args[0] ;
  1632.       dechecked |= 0x4 ;
  1633.       }
  1634.    else parsed = 0 ;
  1635. }
  1636. /*
  1637.  *   This handler sets the chip mem size preset variable.
  1638.  */
  1639. void rexxchip(msg, p)
  1640. struct RexxMsg *msg ;
  1641. char *p ;
  1642. {
  1643.    parseargs(p, 1) ;
  1644.    if ( args[0] == 0 )  {
  1645.       p_chip = 0 ;
  1646.       dechecked |= 0x8 ;
  1647.       rechecked = TRUE ;
  1648.       return ;
  1649.       }
  1650.    if ( ( args[0] > 0 ) && ( args[0] <= TWOMEG) )  {
  1651.       p_chip = args[0] ;
  1652.       dechecked |= 0x8 ;
  1653.       }
  1654.    else parsed = 0 ;
  1655. }
  1656. /*
  1657.  *   This handler sets the chip mem address preset variable.  And yes,
  1658.  *   while it does check to see if the address is in the normal range for
  1659.  *   chip mem as opposed to fast mem, it does allow slow-fast mem addresses
  1660.  *   above the C.0 floor.  If you ask for this slow-fast mem and it isn't
  1661.  *   there, and the WARPS mode is set, there will undoubtedly be a system
  1662.  *   crash, and a jolly good one at that (like, be prepared to run the
  1663.  *   SetClock program with the RESET option, as this program, if mismanaged
  1664.  *   (while in the WARPS mode) can wreak incredible violence on the hardware
  1665.  *   clock and maybe some other things in your custom system that nobody
  1666.  *   knows anything about.)  If you think this is rude, remember, this is
  1667.  *   Rexx command stuff, and if y'all can't get in there with the big dogs,
  1668.  *   you'd best stay on the porch -- so use the Intuition menus instead...
  1669.  */
  1670. void rexxchipa(msg, p)
  1671. struct RexxMsg *msg ;
  1672. char *p ;
  1673. {
  1674.    parseargs(p, 1) ;
  1675.    if (( args[0] >= 0 && args[0] < TWOMEG ) || ( args[0] >= CZERO && args[0] < EZERO ))  {
  1676.        p_chipa = args[0] ;
  1677.        dechecked |= 0x10 ;
  1678.        }
  1679.    else parsed = 0 ;
  1680. }
  1681. /*
  1682.  *   This handler sets the slow-fast mem size preset variable.
  1683.  */
  1684. void rexxsf(msg, p)
  1685. struct RexxMsg *msg ;
  1686. char *p ;
  1687. {
  1688.    parseargs(p, 1) ;
  1689.    if ( args[0] == 0 )  {
  1690.       p_sf = 0 ;
  1691.       dechecked |= 0x20 ;
  1692.       rechecked = TRUE ;
  1693.       return ;
  1694.       }
  1695.    if ( ( args[0] > 0 ) && ( args[0] <= EIGHTMEG ) )  {
  1696.       p_sf = args[0] ;
  1697.       dechecked |= 0x20 ;
  1698.       }
  1699.    else parsed = 0 ;
  1700. }
  1701. /*
  1702.  *   This handler sets the slow-fast mem address preset variable.
  1703.  */
  1704. void rexxsfa(msg, p)
  1705. struct RexxMsg *msg ;
  1706. char *p ;
  1707. {
  1708.    parseargs(p, 1) ;
  1709.    if ( ( args[0] >= TWOMEG ) && ( args[0] < EZERO ) )  {
  1710.       p_sfa = args[0] ;
  1711.       dechecked |= 0x40 ;
  1712.       }
  1713.    else parsed = 0 ;
  1714. }
  1715. /*
  1716.  *   This handler sets the fast mem size preset variable.  Note that unlike
  1717.  *   with the menu, there is no bounds checking on the fast mem size requested
  1718.  *   through Rexx.
  1719.  */
  1720. void rexxfast(msg, p)
  1721. struct RexxMsg *msg ;
  1722. char *p ;
  1723. {
  1724.    parseargs(p, 1) ;
  1725.    if ( args[0] == 0 )  {
  1726.       p_fast = 0 ;
  1727.       dechecked |= 0x80 ;
  1728.       rechecked = TRUE ;
  1729.       return ;
  1730.       }
  1731.    if ( args[0] >= 0 ) {
  1732.       p_fast = args[0] ;
  1733.       dechecked |= 0x80 ;
  1734.       }
  1735.    else parsed = 0 ;
  1736. }
  1737. /*
  1738.  *   This handler sets the fast mem address preset variable.  Note that
  1739.  *   unlike the menu, there is no upper address bounds checking.  If you
  1740.  *   set this too high while in WARPS mode, it can be gone a long time
  1741.  *   before it gets back around to look for any messages.
  1742.  */
  1743. void rexxfasta(msg, p)
  1744. struct RexxMsg *msg ;
  1745. char *p ;
  1746. {
  1747.    parseargs(p, 1) ;
  1748.    if ( args[0] >= SEVENOH )  {
  1749.       p_fasta = args[0] ;
  1750.       dechecked |= 0x100 ;
  1751.       }
  1752.    else parsed = 0 ;
  1753. }
  1754. /*
  1755.  *   This handler returns the version of the MemMometer program.
  1756.  */
  1757. void rexxversion(msg, p)
  1758. struct RexxMsg *msg ;
  1759. char *p ;
  1760. {
  1761.    userreplied = 1 ;
  1762.    replyRexxCmd(msg, 0L, 0L, VERSION) ;
  1763. }
  1764. #endif
  1765.  
  1766. _cli_parse() {}
  1767. _wb_parse() {}
  1768.